#include "../include/http_context.h"
#include <algorithm>
#include <regex>

namespace http {

HttpContext::HttpContext() 
    : _respStatu(200), 
      _recvStatu(RECV_HTTP_LINE) {}

void HttpContext::reSet() 
{
    _respStatu = 200;
    _recvStatu = RECV_HTTP_LINE;
    _request.reSet();
}

bool HttpContext::parseHttpLine(const std::string& line) 
{
    // 正则表达式：匹配请求方法、路径、查询参数、协议版本
    // 原始正则：(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\?(.*))? (HTTP/1\.[01])(?:\n|\r\n)?
    // (GET|HEAD|POST|PUT|DELETE) : 匹配五个中的一个，存储在matches[1]中
    // ([^?]*) ：- [^?]：匹配 “除了 ? 之外的任意字符”   - *：匹配 0 次或多次（路径可为空）
    // (?:\?(.*))?：
    // - (?:...)：「非捕获组」（不占捕获组索引，仅用于分组逻辑）
    // - \?：匹配 ?（? 是正则特殊字符，需用 \ 转义）
    // - (.*)：「捕获组 3」，匹配任意字符（即查询参数，如 id=123&name=test）
    // - 末尾 ?：表示整个 “?+ 查询参数” 是可选的（请求行可没有查询参数）
    // (HTTP/1\.[01]) ：- HTTP/1\.：匹配 HTTP/1.（. 是正则特殊字符，需用 \ 转义）   - [01]：匹配 “0” 或 “1”（仅支持 HTTP/1.0 或 1.1）   - 括号 () 表示「捕获组 4」
    std::regex reqLineRegex(
        "(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?", 
        std::regex::icase   // 忽略大小写匹配
    );
    std::smatch matches;

    if (!std::regex_match(line, matches, reqLineRegex)) 
    {
        _recvStatu = RECV_HTTP_ERROR;
        _respStatu = 400;           // 无效请求
        return false;
    }

    // 提取请求方法（转为大写）
    _request._method = matches[1];
    std::transform(
        _request._method.begin(), 
        _request._method.end(), 
        _request._method.begin(), 
        ::toupper
    );

    // 提取路径（URL解码，不转换空格）
    _request._path = HttpUtil::urlDecode(matches[2], false);

    // 提取协议版本
    _request._version = matches[4];

    // 解析查询参数（如"?id=1&name=test"）
    std::string queryStr = matches[3];
    std::vector<std::string> queryParts;
    HttpUtil::split(queryStr, "&", &queryParts);

    for (const auto& part : queryParts) 
    {
        size_t eqPos = part.find('=');
        if (eqPos == std::string::npos) 
        {
            _recvStatu = RECV_HTTP_ERROR;
            _respStatu = 400;
            return false;
        }
        std::string key = HttpUtil::urlDecode(part.substr(0, eqPos), true);
        std::string val = HttpUtil::urlDecode(part.substr(eqPos + 1), true);
        _request.setParam(key, val);
    }

    return true;
}

bool HttpContext::parseHttpHead(std::string& line) 
{
    // 移除末尾的换行符
    if (!line.empty() && line.back() == '\n') 
    {
        line.pop_back();
    }
    if (!line.empty() && line.back() == '\r') 
    {
        line.pop_back();
    }

    // 匹配"key: value"格式
    size_t colonPos = line.find(": ");
    if (colonPos == std::string::npos) 
    {
        _recvStatu = RECV_HTTP_ERROR;
        _respStatu = 400; // 无效请求头
        return false;
    }

    std::string key = line.substr(0, colonPos);
    std::string val = line.substr(colonPos + 2);
    _request.setHeader(key, val);

    return true;
}

bool HttpContext::recvHttpLine(net::Buffer* buf) 
{
    if (_recvStatu != RECV_HTTP_LINE) 
    {
        return false;
    }

    // 从缓冲区读取一行
    std::string line = buf->getLineAndPop();
    if (line.empty()) 
    {
        // 缓冲区数据不足一行，检查是否超过最大长度
        if (buf->readAbleSize() > MAX_LINE) 
        {
            _recvStatu = RECV_HTTP_ERROR;
            _respStatu = 414; // URL过长
            return false;
        }
        return true; // 等待更多数据
    }

    // 检查行长度
    if (line.size() > MAX_LINE) 
    {
        _recvStatu = RECV_HTTP_ERROR;
        _respStatu = 414; // URL过长
        return false;
    }

    // 解析请求行
    if (!parseHttpLine(line)) 
    {
        return false;
    }

    // 进入请求头解析阶段
    _recvStatu = RECV_HTTP_HEAD;
    return true;
}

bool HttpContext::recvHttpHead(net::Buffer* buf) 
{
    if (_recvStatu != RECV_HTTP_HEAD) 
    {
        return false;
    }

    while (true) 
    {
        // 读取一行请求头
        std::string line = buf->getLineAndPop();
        if (line.empty()) 
        {
            // 缓冲区数据不足，检查是否超过最大长度
            if (buf->readAbleSize() > MAX_LINE) 
            {
                _recvStatu = RECV_HTTP_ERROR;
                _respStatu = 414; // 请求头过长
                return false;
            }
            return true; // 等待更多数据
        }

        // 检查行长度
        if (line.size() > MAX_LINE) 
        {
            _recvStatu = RECV_HTTP_ERROR;
            _respStatu = 414; // 请求头过长
            return false;
        }

        // 空行表示请求头结束
        if (line == "\n" || line == "\r\n") 
        {
            break;
        }

        // 解析请求头
        if (!parseHttpHead(line)) 
        {
            return false;
        }
    }

    // 进入请求体解析阶段
    _recvStatu = RECV_HTTP_BODY;
    return true;
}

bool HttpContext::recvHttpBody(net::Buffer* buf) 
{
    if (_recvStatu != RECV_HTTP_BODY) 
    {
        return false;
    }

    // 获取Content-Length
    size_t content_len = _request.contentLength();
    if (content_len == 0) 
    {
        // 无请求体，解析完成
        _recvStatu = RECV_HTTP_OVER;
        return true;
    }

    // 计算还需读取的长度
    size_t remaining = content_len - _request._body.size();
    if (remaining == 0) 
    {
        _recvStatu = RECV_HTTP_OVER;
        return true;
    }

    // 从缓冲区读取数据
    size_t readLen = std::min(remaining, buf->readAbleSize());
    _request._body += std::string(buf->readPosition(), readLen);
    buf->moveReadOffset(readLen);

    // 检查是否读取完毕
    if (_request._body.size() == content_len) 
    {
        _recvStatu = RECV_HTTP_OVER;
    }

    return true;
}

void HttpContext::recvHttpRequest(net::Buffer* buf) 
{
    // 按阶段解析，错误或完成后停止
    if (_recvStatu == RECV_HTTP_ERROR || _recvStatu == RECV_HTTP_OVER) 
    {
        return;
    }

    // 解析请求行
    if (_recvStatu == RECV_HTTP_LINE) 
    {
        if (!recvHttpLine(buf)) 
        {
            return;
        }
    }

    // 解析请求头
    if (_recvStatu == RECV_HTTP_HEAD) 
    {
        if (!recvHttpHead(buf)) 
        {
            return;
        }
    }

    // 解析请求体
    if (_recvStatu == RECV_HTTP_BODY) 
    {
        recvHttpBody(buf);
    }
}

} // namespace http